package com.ymt.bpm.service.engine.taskcenter.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.dao.Mapper;
import com.ymt.bpm.model.PSeqflow;
import com.ymt.bpm.service.engine.taskcenter.TaskQueryService;
import com.ymt.bpm.util.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Johnny on 2017/4/14.
 */
@Service
public class TaskQueryServiceImpl implements TaskQueryService {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MDao dao;

    @Override
    public JSONObject todoBpdGroupCount(String tenantId, String loginName, String status, String search, int limit) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put(Const.LOGINNAME, loginName);
        paramMap.put("status", status);
        paramMap.put("search", search);
        paramMap.put("limit", limit);
        List<Map<String, Object>> list = dao.selectList(Mapper.TaskQueryMapper, "todoBpdGroupCount", paramMap);
        int total = 0;
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            total =  list.size();
            for (Map<String, Object> map : list) {
                map.put("BPD_ID", AES.encrypt((String)map.get("BPD_ID")));
                rows.add(JSON.toJSON(map));
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", total);
        return rtn;
    }

    @Override
    public JSONObject getRelatedBpd(String tenantId, String relation, String loginName, String search, int limit) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put(Const.LOGINNAME, loginName);
        paramMap.put("search", search);
        paramMap.put("limit", limit);
        List<Map<String, Object>> list = dao.selectList(Mapper.TaskQueryMapper, "getRelatedBpd"+ StringUtils.capitalize(relation), paramMap);
        int total = 0;
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            total =  list.size();
            for (Map<String, Object> map : list) {
                map.put("BPD_ID", AES.encrypt((String)map.get("BPD_ID")));
                rows.add(JSON.toJSON(map));
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", total);
        return rtn;
    }

    @Override
    public JSONObject todos(String tenantId, String loginName, String bpdId,
                            String search, String filter,
                            String order, String sort, int offset, int limit,
                            String lang, int timezoneOffset) {
        String bpdId1 = null;
        if (bpdId!=null && bpdId.length()>41) {
            bpdId1 = AES.decrypt(bpdId);
        } else if (bpdId!=null && bpdId.length()==41){
            bpdId1 = bpdId;
        }
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put(Const.LOGINNAME, loginName);
        paramMap.put("bpdId", bpdId1);
        paramMap.put("search", search);
        paramMap.put("order", order);
        paramMap.put("sort", sort);

        //filter
        if (filter!=null && filter.length()>0) {
            String[] fs = filter.split("-");
            switch (fs[0]) {
                case "received":
                    paramMap.put("filter", Boolean.parseBoolean(fs[1]) ? " T.RECEIVE_TIME IS NOT NULL " : " T.RECEIVE_TIME IS NULL ");
                    break;
                case "due":
                    if ("warn".equalsIgnoreCase(fs[1])) {
                        String overduePercent = Platform.getString("engine.overdue-percent");
                        if (log.isDebugEnabled()) {
                            log.debug("engine.overdue-percent="+overduePercent);
                        }
                        Date now = DateUtil.getGMTDate();
                        paramMap.put("warn", DateUtil.formatGMTDate(now, DateUtil.DATEFORMATSS_ZH));
                        paramMap.put("now", now.getTime());
                        paramMap.put("overduePercent", overduePercent);
                    } else if ("over".equalsIgnoreCase(fs[1])) {
                        paramMap.put("overdue", DateUtil.getGMTDateForFormat(DateUtil.DATEFORMATSS_ZH));
                    }
                    break;
                case "priority":
                    paramMap.put("filter", " T.PRIORITY="+fs[1]+" ");
                    break;
                default:
                    log.warn("todos default case is invalid.");
            }
        }

        PageHelper.offsetPage(offset, limit);
        List<Map<String, Object>> list = dao.selectList(Mapper.TaskQueryMapper, "todos", paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        if (list!=null && list.size()>0) {
            JSONArray rows = new JSONArray();
            for (Map<String, Object> map : list) {
                JSONObject row = DhxUtil.toFastJsonWithDate(map, lang, timezoneOffset);
                row.put("TI_ID", AES.encrypt(row.getString("TI_ID")));  //encrypt tiid
                rows.add(row);
            }
            rtn.put("rows", rows);
        }
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONObject queryList(String tenantId, String queryName, String loginName, JSONObject queryParams) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put(Const.LOGINNAME, loginName);
        paramMap.put("status", queryParams.getString("status"));
        paramMap.put("search", queryParams.getString("search"));
        paramMap.put("sort", queryParams.getString("sort"));
        paramMap.put("order", queryParams.getString("order"));
        JSONObject cols = new JSONObject();
        JSONObject cols1 = queryParams.getJSONObject("cols");
        if (cols1!=null) {
            cols.putAll(cols1);
            if (cols.containsKey("bpdId")) {
                cols.put("bpdId", AES.decrypt(cols.getString("bpdId")));
            }
        }
        paramMap.put("cols", cols);
        int offset = queryParams.getInteger("offset");
        PageHelper.offsetPage(offset, queryParams.getInteger("limit"));
        List<Map<String, Object>> list = dao.selectList(Mapper.TaskQueryMapper, queryName, paramMap);
        PageInfo pageInfo = new PageInfo(list);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            int timezoneOffset = queryParams.getInteger("timezoneOffset");
            for (Map<String, Object> obj : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(obj, Const.LANG_ZH, timezoneOffset);
                node.put("_ITEM_NO", ++offset);
                if (node.containsKey("TI_ID")) {
                    node.put("TI_ID", AES.encrypt(node.getString("TI_ID")));
                }
                if (node.containsKey("PI_EID")) {
                    node.put("PI_EID", AES.encrypt(node.getString("PI_EID")));
                }
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    public JSONObject getDonesByPiId(String tenantId, String piId, String lang, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("piId", piId);
        List<Map<String, Object>> list = dao.selectList(Mapper.TaskQueryMapper, "getDonesByPiId", paramMap);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        int no = 0;
        if (list!=null && list.size()>0) {
            for (Map<String, Object> obj : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(obj, lang, timezoneOffset, true);
                node.put("_ITEM_NO", ++no);
                if (node.containsKey("tiId")) node.put("tiId", AES.encrypt(node.getString("tiId")));
                if (node.containsKey("piEid")) node.put("piEid", AES.encrypt(node.getString("piEid")));
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", no);
        return rtn;
    }

    @Override
    public JSONObject getSeqflowByPiId(String tenantId, String status, String piId, String lang, int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("piId", piId);
        paramMap.put("status", status);
        List<PSeqflow> list = dao.selectList(Mapper.PSeqflowMapper, "getSeqflowByPiId", paramMap);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        int no = 0;
        if (list!=null && list.size()>0) {
            for (PSeqflow obj : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(obj, lang, timezoneOffset);
                if (node.containsKey("piEid")) node.put("piEid", AES.encrypt(node.getString("piEid")));
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", no);
        return rtn;
    }

}
